home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / OLE2BOOK.ZIP / CHAP02.ZIP / CHAP02 / SCHMOO / POLYWIN.CPP < prev    next >
C/C++ Source or Header  |  1993-03-18  |  7KB  |  267 lines

  1. /*
  2.  * POLYWIN.CPP
  3.  *
  4.  * Window procedure for the polyline drawing window and support functions.
  5.  * This window is not complicated.  On creation it allocates a block of
  6.  * memory for a POLYLINEDATA structure that contains 20 POINTs.  We do not
  7.  * attempt to reallocate this array at all just to maintain simplicity.
  8.  *
  9.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  10.  *
  11.  * Kraig Brockschmidt, Software Design Engineer
  12.  * Microsoft Systems Developer Relations
  13.  *
  14.  * Internet  :  kraigb@microsoft.com
  15.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  16.  */
  17.  
  18.  
  19.  
  20. #include "schmoo.h"
  21.  
  22.  
  23.  
  24. /*
  25.  * PolylineWndProc
  26.  *
  27.  * Purpose:
  28.  *  Window procedure for the polyline drawing window.
  29.  */
  30.  
  31. LRESULT __export FAR PASCAL PolylineWndProc(HWND hWnd, UINT iMsg
  32.     , WPARAM wParam, LPARAM lParam)
  33.     {
  34.     LPCPolyline     ppl;
  35.     PAINTSTRUCT     ps;
  36.     HDC             hDC;
  37.     POINT           pt;
  38.     RECT            rc;
  39.  
  40.     ppl=(LPCPolyline)GetWindowLong(hWnd, PLWL_STRUCTURE);
  41.  
  42.     switch (iMsg)
  43.         {
  44.         case WM_CREATE:
  45.             ppl=(LPCPolyline)((LPCREATESTRUCT)lParam)->lpCreateParams;
  46.             SetWindowLong(hWnd, PLWL_STRUCTURE, (LONG)ppl);
  47.  
  48.             //Since New repaints this window, we need to store the hWnd here.
  49.             ppl->m_hWnd=hWnd;
  50.             ppl->New();
  51.             break;
  52.  
  53.  
  54.         case WM_PAINT:
  55.             hDC=BeginPaint(hWnd, &ps);
  56.             ppl->Draw(hDC, FALSE, TRUE);
  57.             EndPaint(hWnd, &ps);
  58.             break;
  59.  
  60.  
  61.         case WM_LBUTTONDOWN:
  62.             //Stop if we are already at the limit.
  63.             if (CPOLYLINEPOINTS==ppl->m_pl.cPoints)
  64.                 {
  65.                 MessageBeep(0);
  66.                 break;
  67.                 }
  68.  
  69.             //Convert the points into 0-32767 range
  70.             GetClientRect(hWnd, &rc);
  71.             pt=MAKEPOINT(lParam);
  72.             ppl->PointScale(&rc, &pt, FALSE);
  73.  
  74.             ppl->m_pl.rgpt[ppl->m_pl.cPoints++]=pt;
  75.  
  76.             //Draw the lines to this new point only.
  77.             hDC=GetDC(hWnd);
  78.             ppl->Draw(hDC, FALSE, FALSE);
  79.             ReleaseDC(hWnd, hDC);
  80.  
  81.             if (NULL!=ppl->m_pAdv)
  82.                 ppl->m_pAdv->OnPointChange();
  83.  
  84.             break;
  85.  
  86.  
  87.         default:
  88.             return DefWindowProc(hWnd, iMsg, wParam, lParam);
  89.         }
  90.  
  91.     return 0L;
  92.     }
  93.  
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100. /*
  101.  * CPolyline::Draw
  102.  *
  103.  * Purpose:
  104.  *  Paints the current line in the polyline window.
  105.  *
  106.  * Parameters:
  107.  *  hDC             HDC to draw on, could be a metafile or printer DC.
  108.  *  fMetafile       BOOL indicating if hDC is a metafile or not, so we
  109.  *                  can avoid operations that RIP.
  110.  *  fEntire         BOOL indicating if we should draw the entire figure
  111.  *                  or not.
  112.  *
  113.  * Return Value:
  114.  *  None
  115.  */
  116.  
  117. void CPolyline::Draw(HDC hDC, BOOL fMetafile, BOOL fEntire)
  118.     {
  119.     HBRUSH          hBrush;
  120.     HPEN            hPen;
  121.     HGDIOBJ         hObj1, hObj2;
  122.     UINT            i, j;
  123.     UINT            uMM;
  124.     POINT           pt1, pt2;
  125.     RECT            rc;
  126.  
  127.     GetClientRect(m_hWnd, &rc);
  128.  
  129.     /*
  130.      * If the mapping mode is not MM_TEXT, convert the points to
  131.      * whatever mapping mode in in effect before drawing.
  132.      * This specifically supports metafiles in MM_ANISOTROPIC.
  133.      */
  134.     uMM=fMetafile ? MM_TEXT : GetMapMode(hDC);
  135.  
  136.     if (MM_TEXT!=uMM)
  137.         DPtoLP(hDC, m_pl.rgpt, m_pl.cPoints);
  138.  
  139.     hPen=CreatePen(m_pl.iLineStyle, 1, m_pl.rgbLine);
  140.     hObj1=SelectObject(hDC, hPen);
  141.  
  142.     hBrush=CreateSolidBrush(m_pl.rgbBackground);
  143.     hObj2=SelectObject(hDC, hBrush);
  144.     SetBkColor(hDC, m_pl.rgbBackground);
  145.  
  146.     /*
  147.      * Either draw the entire figure or just a single point.  The
  148.      * entire figure also includes erasing the background completely,
  149.      * since hDC may be a metafile DC.  Drawing a single point just
  150.      * updates the figure for that new point.
  151.      */
  152.     if (fEntire || 0==m_pl.cPoints)
  153.         {
  154.         //Erase the background for bitmaps and metafiles.
  155.         SelectObject(hDC, GetStockObject(NULL_PEN));
  156.         Rectangle(hDC, rc.left, rc.top, rc.right+1, rc.bottom+1);
  157.         SelectObject(hDC, hPen);
  158.  
  159.  
  160.         /*
  161.          * If we are drawing the entire figure, then loop through each
  162.          * point drawing a line to each successive point.
  163.          */
  164.  
  165.         for (i=0; i < m_pl.cPoints; i++)
  166.             {
  167.             for (j=i; j < m_pl.cPoints; j++)
  168.                 {
  169.                 pt1=m_pl.rgpt[i];
  170.                 pt2=m_pl.rgpt[j];
  171.                 PointScale(&rc, &pt1, TRUE);
  172.                 PointScale(&rc, &pt2, TRUE);
  173.                 MoveTo(hDC, pt1.x, pt1.y);
  174.                 LineTo(hDC, pt2.x, pt2.y);
  175.                 }
  176.             }
  177.         }
  178.     else
  179.         {
  180.         /*
  181.          * If we are only drawing the last point, just cycle once
  182.          * through previous points.
  183.          */
  184.  
  185.         //Get the last point entered in the array.
  186.         j=m_pl.cPoints-1;
  187.         pt1=m_pl.rgpt[j];
  188.         PointScale(&rc, &pt1, TRUE);
  189.  
  190.         for (i=0; i < j; i++)
  191.             {
  192.             pt2=m_pl.rgpt[i];
  193.             PointScale(&rc, &pt2, TRUE);
  194.  
  195.             MoveTo(hDC, pt1.x, pt1.y);
  196.             LineTo(hDC, pt2.x, pt2.y);
  197.             }
  198.         }
  199.  
  200.     //If we only had one point, draw a dot to indicate it's position.
  201.     if (1==m_pl.cPoints)
  202.         {
  203.         pt1=m_pl.rgpt[0];
  204.         PointScale(&rc, &pt1, TRUE);
  205.         SetPixel(hDC, pt1.x, pt1.y, m_pl.rgbLine);
  206.         }
  207.  
  208.     //Restore original points.
  209.     if (MM_TEXT!=uMM)
  210.         LPtoDP(hDC, m_pl.rgpt, m_pl.cPoints);
  211.  
  212.     SelectObject(hDC, hObj1);
  213.     SelectObject(hDC, hObj2);
  214.     DeleteObject(hBrush);
  215.     DeleteObject(hPen);
  216.     return;
  217.     }
  218.  
  219.  
  220.  
  221.  
  222.  
  223.  
  224.  
  225. /*
  226.  * CPolyline::PointScale
  227.  *
  228.  * Purpose:
  229.  *  Scales a point to or from a relative window coordinate to a 0-32767
  230.  *  coordinate.
  231.  *
  232.  * Parameters:
  233.  *  pRect           LPRECT of the window.
  234.  *  ppt             LPPOINT to convert
  235.  *  fScaleToWindow  BOOL indicating direction of scaling.
  236.  *
  237.  * Return Value:
  238.  *  None
  239.  */
  240.  
  241. void CPolyline::PointScale(LPRECT pRect, LPPOINT ppt, BOOL fScaleToWindow)
  242.     {
  243.     DWORD   cx, cy;
  244.  
  245.     //Window size
  246.     cx=(DWORD)(pRect->right-pRect->left);
  247.     cy=(DWORD)(pRect->bottom-pRect->top);
  248.  
  249.     //Prevent crashes
  250.     if (0L==cx) cx=1;
  251.     if (0L==cy) cy=1;
  252.  
  253.     //Must use DWORD to insure proper scaling.
  254.     if (fScaleToWindow)
  255.         {
  256.         ppt->x=(UINT)(((DWORD)ppt->x*cx) >> 15);
  257.         ppt->y=(UINT)(((DWORD)ppt->y*cy) >> 15);
  258.         }
  259.     else
  260.         {
  261.         ppt->x=(UINT)(((DWORD)ppt->x << 15)/cx);
  262.         ppt->y=(UINT)(((DWORD)ppt->y << 15)/cy);
  263.         }
  264.  
  265.     return;
  266.     }
  267.